﻿using Action = Styx.TreeSharp.Action;
using Styx;
using Styx.Common;
using Styx.Common.Helpers;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Media;

namespace BeastMaster
{
    public partial class Classname : CombatRoutine
    {

        public override string Name { get { return "Beastmaster all Botbases by Pasterke"; } }

        public override WoWClass Class { get { return WoWClass.Hunter; } }

        LocalPlayer Me { get { return StyxWoW.Me; } }

        public override bool WantButton { get { return true; } }

        public override void OnButtonPress()
        {
            Form1 ConfigForm = new Form1();
            ConfigForm.ShowDialog();
        }

        #region Initialize
        public override void Initialize()
        {
            Updater.CheckForUpdate();
            Lua.Events.AttachEvent("MODIFIER_STATE_CHANGED", HandleModifierStateChanged);
        }
        #endregion
        public bool RemoveDeadTargets = true;
        public string rotation;
        public string PetCall;
        private static ulong lastGuid = 0;
        private static Stopwatch fightTimer = new Stopwatch();
        private static Stopwatch pullTimer = new Stopwatch();
        float shotRange = 35;

        private double MyTargetDistance
        {
            get
            {
                return Me.GotTarget ? Me.CurrentTarget.Distance : uint.MaxValue - 1;
            }
        }

        public override void Pulse()
        {
            try
            {

            }
            catch { }
        }

        #region rest
        public override bool NeedRest
        {
            get
            {
                if (!Me.Mounted
                    && !Me.IsFlying
                    && !Me.IsGhost
                    && !Me.OnTaxi)
                {
                    if (Me.GotAlivePet
                        && SpellManager.HasSpell(MendPet)
                        && !buffExists(MendPet, Me.Pet)
                        && Me.Pet.HealthPercent <= BeastMasterSettings.myPrefs.mendpetpercent
                        && SpellManager.CanCast(MendPet))
                    {
                        return true;
                    }
                    if (!BeastMasterSettings.myPrefs.Movement
                        && Me.HealthPercent <= BeastMasterSettings.myPrefs.EatFood
                        && !Me.IsSwimming)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public override void Rest()
        {
            if (Me.GotAlivePet
                && SpellManager.HasSpell(MendPet)
                && !buffExists(MendPet, Me.Pet)
                && Me.Pet.HealthPercent <= BeastMasterSettings.myPrefs.mendpetpercent
                && SpellManager.CanCast(MendPet))
            {
                SpellManager.Cast(MendPet, Me.Pet);
                LogMsg("Mend Pet", 2);
                lastCast = MendPet;
            }
            if (!BeastMasterSettings.myPrefs.Movement
                && Me.HealthPercent <= BeastMasterSettings.myPrefs.EatFood
                && !Me.IsSwimming)
            {
                Styx.CommonBot.Rest.Feed();
            }
        }
        #endregion rest

        #region pull
        public override void Pull()
        {

            if (gotTarget
                && Me.CurrentTarget.Guid != lastGuid)
            {
                fightTimer.Reset();
                lastGuid = Me.CurrentTarget.Guid;
                LogMsg("Killing " + Me.CurrentTarget.Name + " at distance " + System.Math.Round(MyTargetDistance).ToString() + ".", 3);
                pullTimer.Reset();
                pullTimer.Start();

            }
            else
            {
                if (gotTarget
                    && pullTimer.ElapsedMilliseconds > 30 * 1000)
                {
                    LogMsg("Cannot pull " + Me.CurrentTarget.Name + " now.  Blacklist for 3 minutes.", 3);
                    Blacklist.Add(Me.CurrentTarget.Guid, BlacklistFlags.All, TimeSpan.FromMinutes(3));
                }
            }
            if (gotTarget
                && !BeastMasterSettings.myPrefs.Facing)
            {
                Me.CurrentTarget.Face();
            }
            if (gotTarget
                && !BeastMasterSettings.myPrefs.Movement
                && Me.CurrentTarget.Distance > 35)
            {
                MoveInRange(35);
            }
            else
            {
                LogMsg("Starting attack", 3);

                if (gotTarget
                    && Me.IsMoving
                    && !BeastMasterSettings.myPrefs.Movement)
                {
                    WoWMovement.MoveStop();
                }
                if (gotTarget
                    && Me.Level >= 76
                    && !spellOnCooldown(Misdirection)
                    && !buffExists(Misdirection, Me))
                {
                    Lua.DoString("RunMacroText('/cast [@pet,exists] Misdirection');");
                    {
                        LogMsg(">> Misdirection on Pet <<", 3);
                    }
                }
                if (gotTarget
                    && SpellManager.HasSpell(ConcussiveShot)
                    && Me.Level < 76
                    && !spellOnCooldown(ConcussiveShot)
                    && !buffExists(ConcussiveShot, Me.CurrentTarget))
                {
                    if (SpellManager.CanCast(ConcussiveShot))
                    {
                        SpellManager.Cast(ConcussiveShot);
                        LogMsg("Pull with Concussive Shot", 6);
                        lastCast = ConcussiveShot;
                    }
                }
                else if (gotTarget
                    && lastCast != ConcussiveShot
                    && SpellManager.HasSpell(ArcaneShot)
                    && Me.FocusPercent >= 20)
                {
                    if (SpellManager.CanCast(ArcaneShot))
                    {
                        SpellManager.Cast(ArcaneShot);
                        LogMsg("Pull with Arcane Shot", 6);
                    }
                }
                if (gotTarget
                    && !Me.Pet.IsAutoAttacking)
                {
                    Lua.DoString("PetAttack()");
                }
            }
        }
        #endregion pull
        #region Pull Buffs

        public override bool NeedPullBuffs 
        { 
            get 
            {
                CheckPet();
                CallPet();
                RevivePet();
                return false; 
            } 
        }

        public override void PullBuff() { }

        #endregion

        #region Pre Combat Buffs

        public override bool NeedPreCombatBuffs
        {
            get
            {
                if (SpellManager.HasSpell(AspectIronHawk)
                    && !buffExists(AspectIronHawk, Me)
                    && SpellManager.CanCast(AspectIronHawk))
                {
                    SpellManager.Cast(AspectIronHawk);
                    LogMsg("Aspect of the Iron Hawk", 2);
                    lastCast = AspectIronHawk;
                }
                if (SpellManager.HasSpell(TrapLauncher)
                    && !buffExists(TrapLauncher, Me)
                    && SpellManager.CanCast(TrapLauncher))
                {
                    SpellManager.Cast(TrapLauncher);
                    LogMsg("Trap Launcher", 2);
                    lastCast = TrapLauncher;
                }
                CheckPet();
                CallPet();
                RevivePet();
                return false;
            }
        }

        public override void PreCombatBuff() { }

        #endregion

        #region Combat Buffs

        public override bool NeedCombatBuffs
        {
            get
            {
                CheckPet();
                CallPet();
                RevivePet();
                if (gotTarget)
                {
                    myPotion();
                    myFlask();
                }

                AlchemistFlask();

                if (gotTarget)
                {
                    UseTrinket1();
                    UseTrinket2();
                    UseEngiGloves();
                }
                return false;
            }
        }

        public override void CombatBuff() { }

        #endregion

        #region Heal

        public override bool NeedHeal
        {
            get
            {
                if (SpellManager.HasSpell(GiftOfTheNaruu)
                    && !spellOnCooldown(GiftOfTheNaruu)
                    && Me.HealthPercent <= BeastMasterSettings.myPrefs.naruupercent
                    && SpellManager.CanCast(GiftOfTheNaruu))
                {
                    SpellManager.Cast(GiftOfTheNaruu);
                    LogMsg("Gift of the Naruu", 2);
                    lastCast = GiftOfTheNaruu;
                }

                HealthStone();


                return false;
            }
        }

        public override void Heal() { }

        #endregion

        #region Falling

        public void HandleFalling() { }

        #endregion

        #region Combat
        public override void Combat()
        {
            if (Paused) { return; }

            if (buffExists(FeignDeath, Me))
            {
                if (gotTarget) { Me.ClearTarget(); }
                return;
            }

            if (Me.GotAlivePet
                && SpellManager.HasSpell(MendPet)
                && !buffExists(MendPet, Me.Pet)
                && Me.Pet.HealthPercent <= BeastMasterSettings.myPrefs.mendpetpercent
                && SpellManager.CanCast(MendPet))
            {
                SpellManager.Cast(MendPet);
                LogMsg("Mend Pet", 2);
            }
            if (!Me.GotTarget
                && (!BeastMasterSettings.myPrefs.Targeting
                || !Me.GroupInfo.IsInRaid || !Me.IsInInstance)
                && (Me.PetInCombat
                || Me.PetAggro))
            {
                Me.Pet.CurrentTarget.Target();
                Me.Pet.CurrentTarget.Face();
                LogMsg("Taking Pet's Target", 4);
            }
            if (gotTarget
                && !IsInRange(35, Me.CurrentTarget)
                && !BeastMasterSettings.myPrefs.Movement)
            {
                MoveInRange(35);
            }
            if (gotTarget
                && IsInRange(35, Me.CurrentTarget)
                && Me.IsMoving
                && !BeastMasterSettings.myPrefs.Movement)
            {
                WoWMovement.MoveStop();
            }
            if (gotTarget
                && !Me.IsSafelyFacing(Me.CurrentTarget)
                && !BeastMasterSettings.myPrefs.Facing)
            {
                Me.CurrentTarget.Face();
            }
            if (gotTarget
                && addCount >= BeastMasterSettings.myPrefs.startaoe
                && !PauseAoe)
            {

                NeedMisdirection();
                useSteadyshot();
                useFocusfire();
                useBestialwrath();
                useKillcommand();
                useMultiShot();
                useTrap();
                useCobrashot();
                return;
            }
            if (gotTarget
                && addCount < BeastMasterSettings.myPrefs.startaoe)
            {
                NeedMisdirection();
                useCobrashot();
                useSteadyshot();
                useConcussiveshot();
                useSilencingshot();
                useFocusfire();
                useKillshot();
                useSerpentsting();
                useKillcommand();
                useGlaivetoss();
                useDirebeast();
                useBestialwrath();
                useStampede();
                useMurderofcrows();
                useRapidfire();
                useReadiness();
                useBerserking();
                useBloodfurey();
                useLifeblood();
                useArcaneshot();
                return;
            }
        }
        #endregion Combat

        #region SpellChecks
        public bool useConcussiveshot()
        {
            if (gotTarget
                && SpellManager.HasSpell(ConcussiveShot)
                && Me.Level < 76
                && Me.CurrentTarget.ThreatInfo.RawPercent > 75
                && !debuffExists(ConcussiveShot, Me.CurrentTarget)
                && !spellOnCooldown(ConcussiveShot))
            {
                if (SpellManager.CanCast(ConcussiveShot))
                {
                    SpellManager.Cast(ConcussiveShot);
                    LogMsg("Concussive Shot", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useSilencingshot()
        {
            if (gotTarget
                    && SpellManager.HasSpell(SilencingShot)
                    && BeastMasterSettings.myPrefs.UseSilencingShot
                    && (Me.CurrentTarget.IsCasting
                    && Me.CanInterruptCurrentSpellCast)
                    && !spellOnCooldown(SilencingShot))
            {
                if (SpellManager.CanCast(SilencingShot))
                {
                    SpellManager.Cast(SilencingShot);
                    LogMsg("Silencing Shot", 0);
                    return true;
                }
            }
            return false;
        }
        public bool useFocusfire()
        {
            if (gotTarget
                    && SpellManager.HasSpell(FocusFire)
                    && buffStackCount(Frenzy, Me.Pet) >= BeastMasterSettings.myPrefs.focusfirestacks)
            {
                if (SpellManager.CanCast(FocusFire))
                {
                    SpellManager.Cast(FocusFire);
                    LogMsg("Focus Fire", 1);
                    return true;
                }
            }
            return false;
        }
        public bool useKillshot()
        {
            if (gotTarget
                    && SpellManager.HasSpell(KillShot)
                    && !spellOnCooldown(KillShot)
                    && Me.CurrentTarget.HealthPercent <= 20)
            {
                if (SpellManager.CanCast(KillShot))
                {
                    SpellManager.Cast(KillShot);
                    LogMsg("Kill Shot", 4);
                    return true;
                }
            }
            return false;
        }
        public bool useSerpentsting()
        {
            if (gotTarget
                    && SpellManager.HasSpell(SerpentSting)
                    && !debuffExists(SerpentStingAura, Me.CurrentTarget)
                && Me.FocusPercent >= 15)
            {
                if (SpellManager.CanCast(SerpentSting))
                {
                    SpellManager.Cast(SerpentSting);
                    LogMsg("Serpent Sting", 1);
                    return true;
                }
            }
            return false;
        }
        public bool useGlaivetoss()
        {
            if (gotTarget
                    && SpellManager.HasSpell(GlaiveToss)
                    && !spellOnCooldown(GlaiveToss)
                    && Me.FocusPercent >= 15
                && debuffExists(SerpentStingAura, Me.CurrentTarget))
            {
                if (SpellManager.CanCast(GlaiveToss))
                {
                    if (!Me.GroupInfo.IsInRaid
                        || !Me.IsInInstance
                        && !spellOnCooldown(Misdirection)
                        && !buffExists(Misdirection, Me))
                    {
                        Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                        //LogMsg(">> Misdirection with Glaive Toss<<", 6);
                    }
                    SpellManager.Cast(GlaiveToss);
                    LogMsg("Glaive Toss", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useDirebeast()
        {
            if (gotTarget
                    && SpellManager.HasSpell(DireBeast)
                    && !spellOnCooldown(DireBeast)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss)))
            {
                if (SpellManager.CanCast(DireBeast))
                {
                    SpellManager.Cast(DireBeast);
                    LogMsg("Dire Beast", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useKillcommand()
        {
            if (gotTarget
                    && SpellManager.HasSpell(KillCommand)
                    && !spellOnCooldown(KillCommand)
                    && Me.FocusPercent >= 40
                && debuffExists(SerpentStingAura, Me.CurrentTarget))
            {
                if (SpellManager.CanCast(KillCommand))
                {
                    SpellManager.Cast(KillCommand);
                    LogMsg("Kill Command", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useBestialwrath()
        {
            if (gotTarget
                    && SpellManager.HasSpell(BestialWrath)
                    && !spellOnCooldown(BestialWrath)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                && debuffExists(SerpentStingAura, Me.CurrentTarget))
            {
                if (SpellManager.CanCast(BestialWrath))
                {
                    SpellManager.Cast(BestialWrath);
                    LogMsg("Bestial Wrath", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useStampede()
        {
            if (gotTarget
                    && SpellManager.HasSpell(Stampede)
                    && !spellOnCooldown(Stampede)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                    && (BeastMasterSettings.myPrefs.stampede == 1
                    || (BeastMasterSettings.myPrefs.stampede == 2 && IsBoss)))
            {
                if (SpellManager.CanCast(Stampede))
                {
                    SpellManager.Cast(Stampede);
                    LogMsg("Stampede", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useMurderofcrows()
        {
            if (gotTarget
                    && SpellManager.HasSpell(MurderOfCrows)
                    && !spellOnCooldown(MurderOfCrows)
                    && !debuffExists(MurderOfCrows, Me.CurrentTarget)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                    && (BeastMasterSettings.myPrefs.murderofcrows == 1
                    || (BeastMasterSettings.myPrefs.murderofcrows == 2 && IsBoss))
                && debuffExists(SerpentStingAura, Me.CurrentTarget)
                && Me.FocusPercent >= 60)
            {
                if (SpellManager.CanCast(MurderOfCrows))
                {
                    SpellManager.Cast(MurderOfCrows);
                    LogMsg("A Murder of Crows", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useRapidfire()
        {
            if (gotTarget
                    && SpellManager.HasSpell(RapidFire)
                    && !spellOnCooldown(RapidFire)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                    && (BeastMasterSettings.myPrefs.rapidfire == 1
                    || (BeastMasterSettings.myPrefs.rapidfire == 2 && IsBoss)))
            {
                if (SpellManager.CanCast(RapidFire))
                {
                    SpellManager.Cast(RapidFire);
                    LogMsg("Rapid Fire", 4);
                    return true;
                }
            }
            return false;
        }
        public bool useReadiness()
        {
            if (gotTarget
                    && SpellManager.HasSpell(Readiness)
                    && !spellOnCooldown(Readiness)
                    && !buffExists(RapidFire, Me)
                    && spellOnCooldown(RapidFire)
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                    && (BeastMasterSettings.myPrefs.Readiness == 1
                    || (BeastMasterSettings.myPrefs.Readiness == 2 && IsBoss)))
            {
                if (SpellManager.CanCast(Readiness))
                {
                    SpellManager.Cast(Readiness);
                    LogMsg("Readiness", 4);
                    return true;
                }
            }
            return false;
        }
        public bool useBerserking()
        {
            if (gotTarget
                && SpellManager.HasSpell(Berserking)
                && !spellOnCooldown(Berserking)
                && !buffExists(RapidFire, Me)
                && !Me.HasAura("Time Warp")
                && !Me.HasAura("Bloodlust")
                && !Me.HasAura("Heroism")
                && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                && (BeastMasterSettings.myPrefs.lifeblood == 1
                || (BeastMasterSettings.myPrefs.lifeblood == 2 && IsBoss)))
            {
                if (SpellManager.CanCast(Berserking))
                {
                    SpellManager.Cast(Berserking);
                    LogMsg("Berserking", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useBloodfurey()
        {
            if (gotTarget
                && SpellManager.HasSpell(BloodFury)
                && !spellOnCooldown(BloodFury)
                && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss))
                && (BeastMasterSettings.myPrefs.bloodfury == 1
                || (BeastMasterSettings.myPrefs.bloodfury == 2 && IsBoss)))
            {
                if (SpellManager.CanCast(BloodFury))
                {
                    SpellManager.Cast(BloodFury);
                    LogMsg("Bloodfury", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useLifeblood()
        {
            if (gotTarget
                    && SpellManager.HasSpell(Lifeblood)
                    && !spellOnCooldown(Lifeblood)
                    && !Me.HasAura("Time Warp")
                    && !Me.HasAura("Bloodlust")
                    && !Me.HasAura("Heroism")
                    && (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownNormalMobs
                    || (Me.CurrentTarget.HealthPercent > BeastMasterSettings.myPrefs.cooldownBosses && IsBoss)))
            {
                if (SpellManager.CanCast(Lifeblood))
                {
                    SpellManager.Cast(Lifeblood);
                    LogMsg("Lifeblood", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useArcaneshot()
        {
            if (gotTarget
                && SpellManager.HasSpell(ArcaneShot)
                && Me.FocusPercent >= 41
                && debuffExists(SerpentStingAura, Me.CurrentTarget))
            {
                if (SpellManager.CanCast(ArcaneShot))
                {
                    SpellManager.Cast(ArcaneShot);
                    LogMsg("Arcane Shot", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useCobrashot()
        {
            if (gotTarget
                && Me.Level >= 81
                && SpellManager.HasSpell(CobraShot)
                && Me.FocusPercent <= 40)
            {
                if (SpellManager.CanCast(CobraShot))
                {
                    SpellManager.Cast(CobraShot);
                    LogMsg("Cobra Shot", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useSteadyshot()
        {
            if (gotTarget
                && Me.Level < 81
                && SpellManager.HasSpell(SteadyShot)
                && Me.FocusPercent <= 40)
            {
                if (SpellManager.CanCast(SteadyShot))
                {
                    SpellManager.Cast(SteadyShot);
                    LogMsg("Steady Shot", 3);
                    return true;
                }
            }
            return false;
        }
        public bool useMultiShot()
        {
            if (gotTarget
                && SpellManager.HasSpell(MultiShot)
                && Me.FocusPercent >= 40)
            {
                if (!Me.GroupInfo.IsInRaid
                    || !Me.IsInInstance
                    && !spellOnCooldown(Misdirection)
                    && !buffExists(Misdirection, Me))
                {
                    Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                    //LogMsg(">> Misdirection with Glaive Toss<<", 6);
                }
                if (SpellManager.CanCast(MultiShot))
                {
                    SpellManager.Cast(MultiShot);
                    return true;
                }
            }
            return false;
        }
        public bool useTrap()
        {
            if (gotTarget
                && SpellManager.HasSpell(ExplosiveTrap)
                && !spellOnCooldown(ExplosiveTrap)
                && buffExists(TrapLauncher, Me))
            {
                Lua.DoString("CastSpellByName('Explosive Trap');");
                {
                    SpellManager.ClickRemoteLocation(StyxWoW.Me.CurrentTarget.Location);
                    LogMsg(">> Explosive Trap <<", 6);
                    LastSpell = "Explosive Trap";
                    return true;
                }
            }
            return false;
        }
        #endregion Spellchecks

    }
}